//
// Created by liuyang on 2025/5/21.
//

#ifndef SERVER_LOG_H
#define SERVER_LOG_H
#include "stdint.h"
#include "iostream"
#include "string"
#include "list"
#include "memory"
#include "fstream"
#include "vector"
#include "sstream"


namespace sylar{
class LogEvent{
public:
    typedef std::shared_ptr<LogEvent> ptr;
    LogEvent();
    const char * getFile() const{
        return m_file;
    };
    int32_t getLine() const{return m_line;};
    uint32_t getElapse() const{
        return m_elapse;
    }
    uint32_t getThreadId() const{
        return m_threadId;
    }
    uint32_t getFiberId() const{return m_fiberId;};
    uint64_t getTime() const{
        return m_time;
    };

    std::string getContent() const{
        return m_content;
    }

private:
    const char* m_file= nullptr;
    int32_t m_line=0;
    uint32_t  m_elapse=0;
    uint32_t m_threadId=0;
    uint32_t m_fiberId=0;//协程id;
    uint64_t m_time=0;
    std::string m_content;
};

class LogLevel{
public:
    enum Level{
        UNKOWN=-1,
        DEBUG=1,
        INFO=2,
        WARN=3,
        ERROR=4,
        FATAL=5
    };

    static const char * Tostring(LogLevel::Level level);
};

class LogFormatter{
public:
    typedef std::shared_ptr<LogFormatter> ptr;
    std::string format(LogLevel::Level level,LogEvent::ptr event);
    LogFormatter(const std::string& pattern);

public:
    class FormatItem{
    public:
        typedef std::shared_ptr<FormatItem> ptr;
        virtual ~FormatItem();
        virtual void format(std::ostream& os,LogLevel::Level level,LogEvent::ptr event)=0;
    };

    void init();

private:
    std::vector<FormatItem::ptr> m_items;
    std::string m_pattern;

};

class LogAppender{
public:
    typedef std::shared_ptr<LogAppender> ptr;
    virtual ~LogAppender();
    virtual void log(LogLevel::Level level,LogEvent::ptr event)=0;

    void setFormatter(LogFormatter::ptr formatter){
        m_formatter=formatter;
    }
    LogFormatter::ptr getFormatter(){
        return m_formatter;
    }

protected:
    LogLevel::Level m_level;
    LogFormatter::ptr m_formatter;
};

class Logger{
public:
    typedef std::shared_ptr<Logger> ptr;
    Logger(const std::string& name="root");
    void log(LogLevel::Level level,LogEvent::ptr event);

    void debug(LogEvent::ptr event);
    void info(LogEvent::ptr  event);
    void warn(LogEvent::ptr  event);
    void error(LogEvent::ptr  event);
    void fatal (LogEvent::ptr  event);

    void addAppender(LogAppender::ptr  appender);
    void delAppender(LogAppender::ptr appender);
    LogLevel::Level getLevel(){
        return m_level;
    }
    void setLevel(LogLevel::Level level){
        m_level=level;
    }

private:
    std::string m_name;
    LogLevel::Level m_level;
    std::list<LogAppender::ptr> m_logAppenders;


};

class StdoutLogAppender : public LogAppender{
public:
    std::shared_ptr<StdoutLogAppender> ptr;
    void log(LogLevel::Level level,LogEvent::ptr event) override;
};

class FileLogAppender:public LogAppender{
public:
    std::shared_ptr<FileLogAppender> ptr;
    FileLogAppender(const std::string& fileanme){
        m_name=fileanme;
    };
    void log(LogLevel::Level level,LogEvent::ptr event) override;

    //重新打开文件，返回true
    bool reopen();

private:
    std::string m_name;
    std::ofstream m_filestream;

};

}

#endif //SERVER_LOG_H
